/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sistema;

import java.awt.Component;
import java.util.Calendar;
import java.util.Date;
import java.util.TreeMap;
import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import validacao.Exception.TamanhoNomeException;
import validacao.Exception.campoPreenchidoException;
import validacao.Exception.contratacaoException;
import validacao.Exception.cpfInvalidoException;
import validacao.Exception.idadeInvalidaException;
import validacao.Exception.salarioException;
import validacao.Exception.valorEmprestimoException;

/**
 *
 * @author Rodrigo
 */
public class validacao {
    
    final long idadeMinima = 21;
    final long idadeMaximaHomem = 65;
    final long idadeMaximaMulher = 61;
    final long idadeMinimaContratacao = 18;
    final long idadeMaximaContratacao = 60;
    final double pisoSalarial = 500;
    final double tetoSalarial = 100000;
    
    public boolean validarCPF(String cpf) throws cpfInvalidoException{
        int     d1, d2, digito1, digito2, digitoCPF;  
  
        d1 = d2 = 0;  
        digito1 = digito2  = 0;  
  
        for (int contador = 1; contador < cpf.length() -1; contador++)  
        {
            
           digitoCPF = Integer.valueOf (cpf.substring(contador -1, contador)).intValue();  
   
           d1 +=  ( 11 - contador ) * digitoCPF;  
    
           d2 +=  ( 12 - contador ) * digitoCPF;  
        }  
        
        digito1 = setDigito(d1);
        
        digito2 = setDigito(d2+2*digito1);
    
        if(valido(digito1,digito2,cpf.substring(cpf.length()-2,cpf.length())))
        {
            return true;
        }
        else
        {
            throw new cpfInvalidoException ("cpf inválido");
        }
    }

    private int setDigito(int digito) {
        if(digito % 11 < 2)
            return 0;
        else
            return 11 - (digito % 11);            
    }

    private boolean valido(int digito1, int digito2, String digVerificador) {
        return digVerificador.equals(String.valueOf(digito1) + String.valueOf(digito2));
    }
    
    public boolean cpfExiste(String cpf,TreeMap<String,Empregado> empregados){
        return empregados.containsKey(cpf);
    }
    
    public boolean validaEmprestimo (Empregado empregado) throws idadeInvalidaException{
        if(homem(empregado))
            return idadeOk(empregado,idadeMaximaHomem);
        else
            return idadeOk(empregado,idadeMaximaMulher);
    }

    private boolean homem(Empregado empregado) {
        return empregado.getSexo().equalsIgnoreCase("masculino");
    }

    private boolean idadeOk(Empregado empregado, long idadeMaxima) throws idadeInvalidaException {
        long idade = empregado.getIdade();
        if(idade >= idadeMinima && idade <= idadeMaxima)
            return true;
        else
            throw new idadeInvalidaException ("Idade deve ser entre "+idadeMinima+" e "+idadeMaxima+" anos.");
    }
    
    public boolean validaContratacao (Calendar dataNascimento, Calendar dataAdmissao) throws contratacaoException{
        if(calcularIdade(dataNascimento) <= idadeMaximaContratacao)
            return (calcularIdade(dataNascimento) >= idadeMinimaContratacao) && dataAdmissaoOk(dataAdmissao,dataNascimento);
        else
            throw new contratacaoException ("A idade deve ser de "+idadeMinimaContratacao+" a "+idadeMaximaContratacao+" e a data de admissao não pode ser depois de "+Calendar.getInstance().getTime().toString());
    }

    private long calcularIdade(Calendar dataNascimento) {
        int fator = 0;
        
        Calendar calendarioHoje = Calendar.getInstance();
        
        calendarioHoje.setTime(new Date());
        
        if(calendarioHoje.get(Calendar.DAY_OF_YEAR) < dataNascimento.get(Calendar.DAY_OF_YEAR)) {
              fator = -1; 
        }
        
        return (calendarioHoje.get(Calendar.YEAR) - dataNascimento.get(Calendar.YEAR) + fator);
    }

    //se o mês de admissão for o mês atual, a função retorna falso. Por que?
    public boolean dataAdmissaoOk(Calendar dataAdmissao, Calendar dataNascimento) {
        Calendar tomorrow = Calendar.getInstance();
        tomorrow.add(Calendar.DAY_OF_MONTH,1);
        return dataAdmissao.after(dataNascimento) && dataAdmissao.before(tomorrow);
    }
    
    public boolean checaTamanhoNome (String nome) throws TamanhoNomeException{
        if(nome.length() < 3 || nome.length() > 100)
            throw new TamanhoNomeException("Nome deve ter no mínimo 3 e no máximo 100 caracteres");
        else
            return true;
    }
    
    public boolean confirmaCamposPreenchidos (JPanel painel) throws campoPreenchidoException{
        Component component[] = painel.getComponents();
        for(int i = 0; i < component.length; i++)
        {
            if(campoVazio(component[i]))
            {
                throw new campoPreenchidoException ("Todos os campos devem ser preenchidos");
            }
        }
        return true;
    }

    private boolean campoVazio(Component component) {
        if(component instanceof JFormattedTextField)
        {
            if(((JFormattedTextField)component).getText().isEmpty() || ((JFormattedTextField)component).getText().startsWith(" "))
            {
                return true;
            }
        }
        return false;
    }
    
    public boolean validaSalario (double salario) throws salarioException{
        if((salario >= pisoSalarial) && (salario <= tetoSalarial))
            return true;
        else
            throw new salarioException("o salário deve estar entre "+pisoSalarial+" e "+tetoSalarial);
    }
    
    public boolean validaValorEmprestimo (Empregado empregado,double valoremprestimo) throws valorEmprestimoException{
        if(homem(empregado))
        {
            if (valorOKHomem(empregado.getIdade(),empregado.getSalario(),valoremprestimo))
                return true;
            else
                throw new valorEmprestimoException ("valor de emprestimo inválido");
        }
        else
        {
            if(valorOKMulher(empregado.getIdade(),empregado.getSalario(),valoremprestimo))
                return true;
            else
                throw new valorEmprestimoException ("valor de emprestimo inválido");
        }
    }

    private boolean valorOKHomem(long idade, double salario, double valoremprestimo) {
        if(idade <= 35)
        {
            if(salario >= 5000)
                return valoremprestimo <= salario * 0.70;
            else
                return valoremprestimo <= salario * 0.60;
        }
        else if(idade <= 45)
        {
            if(salario >= 6000)
                return valoremprestimo <= salario * 0.55;
            else
                return valoremprestimo <= salario * 0.45;
        }
        else
        {
            return valoremprestimo <= salario * 0.35;
        }  
    }

    private boolean valorOKMulher(long idade, double salario, double valoremprestimo) {
        if(idade <= 30)
                return valoremprestimo <= salario * 0.75;
        else if(idade <= 44)
                return valoremprestimo <= salario * 0.55;
        else
                return valoremprestimo <= salario * 0.40;
    }


    
}